﻿using Kimd.Common;
using Kimd.Communication;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WorkStation.Common;

namespace WorkStation.Logic
{
    /// <summary>
    /// 贴合逻辑
    /// </summary>
    public class PasteLogic : FlowBase
    {
        private Axis _x;
        private Axis _y;
        private Axis _y2;
        private Axis _z;
        private Cylinder _upLight;
        private Cylinder _downLight;
        private Cylinder _plasmaStart;
        private Cylinder _airDrainage;
        private Cylinder _vac;
        private Cylinder _cleanUpdown;
        private Cylinder _dispense;
        private Sensor _vacSensed;
        private Sensor _zOrigin;
        private Sensor _zPressureOverload;
        private Sensor _gtOK;

        private CommunicationHelper _vision;
        private Tray _blockTray;
        public PasteLogic(string flowName, FlowManager flowmanager)
            : base(flowName, flowmanager)
        {
            _x = MachineResource.Instance.MachineAxis["贴合X直线"];
            _y = MachineResource.Instance.MachineAxis["贴合Y1直线"];
            _y2 = MachineResource.Instance.MachineAxis["贴合Y2直线"];
            _plasmaStart = MachineResource.Instance.MachineCylinder["等离子机启动"];
            _airDrainage = MachineResource.Instance.MachineCylinder["废气真空"];
            _upLight = MachineResource.Instance.MachineCylinder["上相机光源"];
            _downLight = MachineResource.Instance.MachineCylinder["下相机光源"];
            _vac = MachineResource.Instance.MachineCylinder["贴合吸嘴真空吸"];
            _cleanUpdown = MachineResource.Instance.MachineCylinder["清洁上下气缸"];
            _dispense = MachineResource.Instance.MachineCylinder["点胶触发"];
            _zOrigin = MachineResource.Instance.MachineSensor["压力原点"];
            _zPressureOverload = MachineResource.Instance.MachineSensor["压力超限"];
            _gtOK = MachineResource.Instance.MachineSensor["GT2测量OK"];
            _vacSensed = MachineResource.Instance.MachineSensor["贴合吸嘴真空感应"];

            _vision = new CommunicationHelper("视觉", MachineResource.Instance.MachineTcpClient["视觉"]);
            _blockTray = new Tray(10, 4);

            RegisterDirectSignal("Block取完");
            RegisterDirectSignal("贴Block结束");

            isBlockDone = false;
        }

        public override void Calibrate()
        {
            base.Calibrate();
        }

        public override void Home()
        {
            if (_x.ServoWarn)
                _x.ClearAlarm();
            Thread.Sleep(200);
            if (!_x.ServoOn)
                _x.SetServoOn();
            if (_y.ServoWarn)
                _y.ClearAlarm();
            Thread.Sleep(200);
            if (!_y.ServoOn)
                _y.SetServoOn();
            if (_y2.ServoWarn)
                _y2.ClearAlarm();
            Thread.Sleep(200);
            if (!_y2.ServoOn)
                _y2.SetServoOn();
            //Z轴抬起

            _upLight.Off();
            _downLight.Off();
            _airDrainage.Off();
            _plasmaStart.Off();
            //SingleCylinderOperate(_cleanUpdown, 5000, false);
            _cleanUpdown.Off();
            if (!CheckFlowCondition()) return;

            AxisGoHomeSimultaneously(new List<Axis>() { _x, _y });
            if (!CheckFlowCondition()) return;

            checkProductStatus();
        }

        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }

        public override void InSingleRunMode()
        {
            base.InSingleRunMode();
        }

        bool isBlockDone = false;
        public override void Method()
        {
            List<double> pos;
            if (!CheckFlowCondition()) return;

            if (!GlobalVariable.IsDryRun)
            {
                WaitForSignal("贴合轨道", "贴合轨道板到位");
                if (!CheckFlowCondition()) return;
            }

            //Z轴抬起
            while (!safetyCheck() && !IsBreak())
            {
                Thread.Sleep(20);
            }
            if (!CheckFlowCondition()) return;

            for (int i = 0; i < 2; i++)
            {
                #region 拍照&喷胶
                for (int j = 0; j < 4; j++)
                {
                    _upLight.On();
                    AxisMoveSimultaneously(_x, _y, $"芯片{i + 1}矩阵-{j}-{0}");
                    if (!CheckFlowCondition()) return;
                    //视觉
                    if (!GlobalVariable.IsDryRun)
                    {
                    retry:
                        SendPackage sp = new SendPackage();
                        sp.Message = $"Trigger,AimUpCam,{_x.Position},{_y.Position},{0},{j + 1}";
                        TcpClientSendAndReceive(_vision, sp, 5000, 0, out string recvStr);
                        if (!CheckFlowCondition()) return;
                        if (recvStr.Equals("NG"))
                        {
                            ShowWarnAndPause("上相机拍照异常", "贴合模组");
                            if (!CheckFlowCondition()) return;
                            goto retry;
                        }
                    }
                    else
                        Thread.Sleep(500);
                    _upLight.Off();
                    //点胶
                    if (GlobalVariable.IsDryRun)
                    {
                        double _dispensOffsetX = -60;
                        double _dispensOffsetY = 0;
                        pos = new List<double>();
                        pos.Add(_x.MotionPosition[$"芯片{i + 1}矩阵-{j}-{0}"] + _dispensOffsetX);
                        pos.Add(_y.MotionPosition[$"芯片{i + 1}矩阵-{j}-{0}"] + _dispensOffsetY);
                        //Z轴抬起
                        while (!safetyCheck() && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        if (!CheckFlowCondition()) return;
                        AxisMoveSimultaneously(new List<Axis>() { _x, _y }, pos);
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {

                    }
                    _dispense.On();
                    if (GlobalVariable.IsDryRun)
                    {
                        //需要等待点胶完成吗？
                        Thread.Sleep(500);
                    }
                    _dispense.Off();
                }
                #endregion

                while(!CheckSignal("Block供料", "Block可取料") && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                #region 取Block&贴合
                for (int k = 0; k < 4; k++)
                {
                    #region 取Block
                regetblock:
                    if (!CheckFlowCondition()) return;
                    //Z轴抬起
                    while (!safetyCheck() && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    //取block
                    int getIndex = _blockTray.Helper.GetFirstIndex(CellStatus.HasProduct);
                    AxisMoveSimultaneously(_x, _y, $"Block取料矩阵-{getIndex}-{0}");
                    if (!CheckFlowCondition()) return;
                    //Z轴下降到取block高度

                    NozzleGetProduct(null, _vac, _vacSensed, 5000, delayAfterOpenVac: 100, 0, delayBeforeVacCheck: 100, GlobalVariable.IsDryRun);
                    if (!CheckFlowCondition()) return;

                    //Z轴抬起

                    //刷新block tray
                    _blockTray.Helper.SetCellStatus(getIndex, CellStatus.NoProduct);
                    if (_blockTray.Helper.IsEmpty)
                    {
                        WaitForSignal("Block供料", "Block可取料");
                        SetSignal("Block取完");
                        isBlockDone = true;
                    }
                    //Z轴抬起
                    while (!safetyCheck() && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    #endregion

                    #region 清洁
                    AxisMoveSimultaneously(_x, _y, "清洁位");
                    if (!CheckFlowCondition()) return;

                    _airDrainage.On();
                    _plasmaStart.On();

                    //Z轴降到清洁高度

                    //清洁延时
                    Thread.Sleep(500);

                    _airDrainage.Off();
                    _plasmaStart.Off();

                    //Z轴抬起
                    while (!safetyCheck() && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    #endregion

                    #region GT量测&抛料
                    retryGT:
                    //GT测高
                    AxisMoveSimultaneously(_x, _y, "GT量测位");
                    if (!CheckFlowCondition()) return;

                    //Z下降到GT量测高度

                    //量测延时
                    Thread.Sleep(400);

                    //判断测高结果决定是否抛料
                    if (!GlobalVariable.IsDryRun)
                    {
                        if (!_gtOK.WaitOn())
                        {
                            ShowWarnAndPause("GT量测Block NG", "贴合模组");
                            if (!CheckFlowCondition()) return;
                            if (MessageBox.Show("是否重试?", "量测失败", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                goto retryGT;
                            else
                            {
                                AxisMoveSimultaneously(_x, _y, "Block抛料位");
                                if (!CheckFlowCondition()) return;
                                _vac.Off();
                                Thread.Sleep(1000);
                                if (isBlockDone)
                                {
                                    WaitForSignal("Block供料", "Block可取料");
                                    goto regetblock;
                                }
                                else
                                    goto regetblock;
                            }
                        }
                    }
                    //Z轴抬起
                    while (!safetyCheck() && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    #endregion

                    #region 过下相机
                    _downLight.On();
                    AxisMoveSimultaneously(_x, _y, "下相机拍照位");
                    if (!CheckFlowCondition()) return;
                    if (!GlobalVariable.IsDryRun)
                    {

                    }
                    else
                        Thread.Sleep(500);
                    _downLight.Off();
                    #endregion

                    #region 贴合
                    if (GlobalVariable.IsDryRun)
                    {
                        double _pasteOffsetX = 80;
                        double _pasteOffsetY = 60;
                        pos = new List<double>();
                        pos.Add(_x.MotionPosition[$"芯片{i + 1}矩阵-{k}-{0}"] + _pasteOffsetX);
                        pos.Add(_y.MotionPosition[$"芯片{i + 1}矩阵-{k}-{0}"] + _pasteOffsetY);
                        //Z轴抬起
                        while (!safetyCheck() && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        if (!CheckFlowCondition()) return;
                        AxisMoveSimultaneously(new List<Axis>() { _x, _y }, pos);
                        if (!CheckFlowCondition()) return;

                        //Z轴下降到贴附高度

                        //Z轴抬起，贴附结束
                        Thread.Sleep(1000);
                    }
                    else
                    {

                    }
                    //Z轴抬起
                    while (!safetyCheck() && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    #endregion
                }
                #endregion
            }

            SetSignal("贴Block结束");
        }

        public override void OnStop()
        {
            base.OnStop();
        }

        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }

        public override void SpotCheck()
        {
            base.SpotCheck();
        }

        private bool safetyCheck()
        {
            return true;
        }

        public void NewBlockTray()
        {
            this._blockTray.Helper.NewFullTray();
        }
        public void checkProductStatus()
        {
        restart:
            if (_vacSensed.WaitOn())
            {
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"贴合头上有料，请取走", this.Description, 0, "系统"));
                //出错，停下所有线程
                _flowManager.Pause();
                //若为报错，需重新检测启动信号
                WaitForStart();
                if (!CheckFlowCondition()) return;
                goto restart;
            }
            _vac.Off();
        }
    }
}
